package com.xcf.center.client;

import com.alibaba.fastjson.JSON;
import com.xcf.center.ServerMeta;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.framework.api.CuratorWatcher;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 服务监控类
 */
public class ServerWatcher {

    private final ServerConfig config;

    private final ServerManager serverManager;

    private CuratorFramework zookeeperClient;

    public ServerWatcher(ServerConfig config) {
        this(config, new ServerManager());
    }

    public ServerWatcher(ServerConfig config, ServerManager serverManager) {
        this.config = config;
        this.serverManager = serverManager;
    }

    public void init() throws Exception {
        CuratorFramework client = CuratorFrameworkFactory.builder()
                .connectString(config.getRegisterConfig().getConnectSting()) // server地址
                .sessionTimeoutMs(config.getRegisterConfig().getSessionTimeOut()) // 会话超时时间
                .connectionTimeoutMs(config.getRegisterConfig().getConnectTimeOut()) // 连接超时时间
                .retryPolicy(config.getRegisterConfig().getRetryPolicy()) // 重试策略
                .build(); //
        client.start();
        System.out.println("Zookeeper session established.");
        zookeeperClient = client;
        initServerAndWatcher();
    }

    protected void initServerAndWatcher() throws Exception {
        Set<String> nameSpaces = config.getNameSpaces();
        for (String nameSpace : nameSpaces) {
            initNameSpaceServer(nameSpace);
        }
    }

    private void initNameSpaceServer(String nameSpace) throws Exception {
        List<String> serverPathList = zookeeperClient.getChildren().forPath(nameSpace);
        List<ServerMeta> serverMetas = new ArrayList<>(serverPathList.size());
        for (String serverPath : serverPathList) {
            byte[] bytes = zookeeperClient.getData().forPath(nameSpace + "/" + serverPath);
            String data = new String(bytes);
            ServerMeta serverMeta = JSON.parseObject(data, ServerMeta.class);
            serverMetas.add(serverMeta);
        }
        serverManager.registerServer(nameSpace, serverMetas);
        zookeeperClient.getChildren().usingWatcher((CuratorWatcher) event -> {
            System.out.println("event = " + event.getType().name());
            if (event.getType() == Watcher.Event.EventType.NodeChildrenChanged) {
                try {
                    initNameSpaceServer(nameSpace);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }).forPath(nameSpace);
    }
}
